
//一些，可选择启用的工具

import {EasyA} from "../common/EasyA";
import {Interceptor} from "../core/Interceptor";
import {EasyACtx} from "../core/EasyACtx";
import {Log} from "../util/Log";
import {Util} from "../util/Util";
import {_} from "../util/UtilTs";
import {TsReflect} from "../util/TsReflect";
import {Ctx} from "../index";


export interface DefaultModuleCtx{
    params: any;
    i18t:(key:string,opt?)=>string
}

export class DefaultModule{
    framework:EasyA;
    constructor(framework){
        this.framework = framework;
    }

    //启用参数集合功能（无论是 url 的，还是 post body 里面的，都集中到 params 里）
    enableParamResolve(options = {multipart:false}) {
        const easya = this.framework;
        const app = this.framework.express;

        //参数
        const bodyParser = require('body-parser');
        app.use(bodyParser.json());
        app.use(bodyParser.urlencoded({ extended: false }));

        class  ParamResolveInterceptor extends Interceptor{

            static getParamsFromObject(target, Obj){
                for (const key in Obj){
                    target[key] =Obj[key];
                }
            }

            before(ctx: EasyACtx) {
                ctx.params = {};
                const expressReq = ctx.req;
                ParamResolveInterceptor.getParamsFromObject(ctx.params,expressReq.query);
                ParamResolveInterceptor.getParamsFromObject(ctx.params,expressReq.body);
                ParamResolveInterceptor.getParamsFromObject(ctx.params,expressReq.files);

                ctx.next();
            }
        }

        //参数集中
        easya.addInterceptor(ParamResolveInterceptor);

    }

    //启用action 的执行详情打印服务
    enableActionLog(){
        const easya = this.framework;
        class ActionLogInterceptor extends Interceptor{

            constructor(){
                super({
                    forceContinue:true,
                });
            }

            static getParams(ctx){
                const params = ctx.params;
                let retStr = "";
                if(params){
                    for (const key in params){
                        retStr +=`${key} = ${params[key]}\r\n`;
                    }
                }
                retStr = _.trimEnd(retStr,'\r\n');
                return retStr;
            }


            static getHandlesReport(logIns,ctx){
                const doFinished = ctx.store.doFinisedHandle; //已经处理了请求的
                let notFinished = _.xor(doFinished,ctx.action.associatedProps.handles);
                notFinished = _.take(notFinished,_.indexOf(notFinished,logIns.afterHandle));

                let retStr = "";

                function appendByColor(colorFunc,arr){
                    _.each(arr,(handle)=>{
                        const from = handle.from;
                        const name = handle.name || TsReflect.getClass(from).name;
                        retStr +=colorFunc(`${name}\r\n`);
                    });
                }
                appendByColor(Log.tools.chalk.green.bold,doFinished);
                appendByColor(Log.tools.chalk.red.bold,notFinished);
                retStr = _.trimEnd(retStr,'\r\n');
                return retStr;
            }

            before(ctx: Ctx){
                ctx.store.doFinisedHandle = [];
                const old = ctx.next;
                ctx.next = function () {
                    if(ctx.handle){
                        ctx.store.doFinisedHandle.push(ctx.handle);
                    }
                    old();
                };
                ctx.next();
            }

            after(ctx: Ctx) {
                const {action,req} = ctx;
                const {log} = Log.tools;
                log();
                Log.info(
`时间: ${Util.now()}
action:${action.name}      请求类型:${req.method}
路由地址:${action.associatedProps.routePath}
参数:
${ActionLogInterceptor.getParams(ctx)}
控制器:${action.controller.name}
请求处理器:
${ActionLogInterceptor.getHandlesReport(this,ctx)}
`);
                log();

                ctx.next();
            }

        }
        easya.addInterceptor(ActionLogInterceptor);

    }

    //国际化字符串
    enableI18n(options) {
        const easya = this.framework;
        const app = this.framework.express;

        const i18next = require('i18next');
        const SyncBackend = require('i18next-sync-fs-backend');


        const i18nConfig = {
            initImmediate: false,
            lng: 'zh_CN',
            fallbackLng: 'zh_CN',
            debug: true,
            resources: {
                en_US: {
                    translation: {
                        "hello":"hello"
                    }
                },
                zh_CN:{
                    translation: {
                        "hello":"你好",
                        "success":"成功",
                    }
                }
            },

            //检测语言
            detectLang(i18n,ctx:Ctx){
                let lang = "";
                if(ctx.params.lang){
                    lang = ctx.params.lang;
                }
                ctx.i18t = i18n.getFixedT(lang);
            }

        };

        _.merge(i18nConfig,options);

        const i18n = i18next
            .use(SyncBackend)
            .init(i18nConfig);




        class  I18nInterceptor extends Interceptor{
            before(ctx: Ctx) {
                i18nConfig.detectLang(i18n,ctx);
                ctx.next();
            }
        }

        easya.addInterceptor(I18nInterceptor);

    }





}
